package _1Decorator

import (
	"log"
	"math"
	"time"
)

// 装饰者模式
// 装饰者模式思想，给原有的函数程序逻辑，添加一些附加操作，
//	装饰了一下，但和原有的本质意义相差不大

// 测试方法：根据传入参数返回一个数据
func Pi(n int) float64 {
	ch := make(chan float64)
	for i := 0; i < n; i++ {
		go func(ch chan float64, i float64) {
			ch <- 4 * math.Pow(-1, i) / (2*i + 1)
		}(ch, float64(i))
	}
	result := 0.0
	for j := 0; j < n; j++ {
		result += <-ch
	}
	return result
}

// PiFunc 定义 类型为 和Pi函数一样的类型
type PiFunc func(int) float64

// WrapLogger 使用装饰者思想：比如给每个数据加上更详细的日志信息
func WrapLogger(fun PiFunc, logger *log.Logger) PiFunc {
	return func(n int) float64 {
		fn := func(n int) (result float64) {
			defer func(t time.Time) {
				logger.Printf("took=%v, n=%v, result=%v", time.Since(t), n, result)
			}(time.Now())
			return fun(n)
		}
		return fn(n)
	}
}
